#### BUILDFILE MACROS
Option().actual=''
Option().extensions=[]
Option().compiler=''
Option().linker=''
Option().dependencies=Dependency()
Option().prefix='/usr/'
Option().sharedir=os.path.join(Option().prefix,'share')
Option().bindir=os.path.join(Option().prefix,'bin')
Option().cflags=[]
Option().ldflags=[]

Private().files={}
Private().data={}
if not 'source_files' in Log():
	Log().source_files={}
if not 'installed' in Log():
	Log().installed=[]

def package(p):
	c='package_'+p
	Option().package=p
	eval(c)()
def target(t):
	c=Option().package+'_'+t
	eval(c)()
def _file_calc_hash(p):
	f=open(p)
	return hashlib.md5(f.read()).hexdigest()
def add_dir(c,d):
	"""
	Scans recursively given directory, searching for files. If category is set
	to 'source', it will only seek for extensions in Option().extensions.
	@type c: string
	@type d: string
	@param c: category
	@param d: directory to search in
	"""
	if not os.path.exists(d):
		warning('Given path '+d+' does not exist.')
	if not c in Private().files:
		  Private().files[c]=[]
	if c=='source':
		for root, dirs, files in os.walk(d):
			for file in files:
				if root.find('/.')!=-1: continue #checking against hidden files
				ext=os.path.splitext(file)[1][1:] #file extension
				if not ext in Option().extensions:
					print 'Found ',root+os.sep+file,'- ommitting'
				else:
					print 'Found ',root+os.sep+file
					Private().files[c].append(os.path.join(root,file))
	else:
		for root, dirs, files in os.walk(d):
			for file in files:
				if root.find('/.')!=-1: continue #checking against hidden files
				print 'Found '+c+' file',root+os.sep+file
				Private().files[c].append(os.path.join(root,file))

def process_build():
	"""
	Launches build procedure. Iterates though all files visited by add_dir
	which are tagged as 'source', compiles them and then links. Binary is named
	equally as the package and it's placed in main project directory.
	"""
	Option().dependencies.check()
	Private().Compiler=_get_compiler(Option().compiler)
	Private().Linker=_get_linker(Option().linker)
	Private().objs=[]
	Private().cflags=str.join(' ',Option().dependencies.cflags())+' '+str.join(' ',Option().cflags)
	Private().ldflags=str.join(' ',Option().dependencies.ldflags())+' '+str.join(' ',Option().ldflags)
	if not 'binname' in Option():
		  Option().binname=Option().package
	Progress().reset()
	#compiling
	
	for f in Private().files['source']:
		objpath=os.path.splitext(f)[0]+'.o '
		if f in Log().source_files:
			  if Log().source_files[f]==_file_calc_hash(f):
				    Private().objs.append(objpath)
				    continue
		if Private().Compiler.compile([f],objpath,Private().cflags)!=0:
			  Log().save()
			  error('Build error,stopping.')
		Log().source_files[f]=_file_calc_hash(f)
		Private().objs.append(objpath)

	Log().save()

	#linking

	print 'Linking..'
	print Private().objs	
	if Private().Linker.compile(Private().objs,Option().binname,Private().ldflags)!=0:
		  error('Linking_error, stoppping.')
	
	print 'Building finished.'

		
def _recursive_del(d):
	"""
	Recursively deletes given directory.
	@type d: string
	@param d: directory
	"""
	if not os.path.exists(d): return
	for root, dirs, files in os.walk(d, topdown=False):
		for name in files:
			os.remove(os.path.join(root, name))
		for name in dirs:
			os.rmdir(os.path.join(root, name))
	os.rmdir(d)


#### BUILD.PY CODE

def die(text):
	print text
	exit()
def error(text):
	print 'ERROR :',text
	exit()
def warning(text):
	print 'WARNING :',text


